#!/usr/bin/evn python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   文件名称 :     __init__.py
   文件功能描述 :   功能描述
   创建人 :       小钟同学
   创建时间 :          2021/11/29
-------------------------------------------------
   修改描述-2021/11/29:

代码来自：https://githug.com/xloem/async_to_sync/tree/master/async_to_sync

-------------------------------------------------
"""
import asyncio
import atexit
import threading

_loop = None
_thread = None


def get_default_event_loop():
    global _loop, _thread
    if _loop is not None:
        return _loop
    _loop = _loop or asyncio.get_event_loop()
    _thread = _thread or threading.Thread(target=_loop.run_forever, daemon=True)
    if not _loop.is_running():
        _thread.start()
    return _loop


def set_default_event_loop(loop):
    stop()
    _loop = loop


def start():
    get_default_event_loop()


@atexit.register
def stop():
    global _loop, _thread
    if _loop is not None:
        _loop.call_soon_threadsafe(_loop.stop)
    if _thread is not None:
        _thread.join()
        _thread = None


def coroutine(coroutine, loop=None):
    if loop is None:
        loop = get_default_event_loop()
    future = asyncio.run_coroutine_threadsafe(coroutine, loop)
    result = future.result()
    return result


def function(function, loop=None):
    def call(*params, **kwparams):
        async_coroutine = function(*params, **kwparams)
        return coroutine(async_coroutine, loop)

    return call


# 把异步转为同步函数，这样同步函数可以直接的在协程函数里面不需要使用 await
def sync_to_async_wrapper(f):
    def wrapper(*args, **kwargs):
        asyncio.get_event_loop().create_task(f(*args, **kwargs))

    return wrapper


class methods:
    def __init__(self, object, loop=None):
        self.__object = object
        self.__loop = loop

    def __getattr__(self, name):
        result = getattr(self.__object, name)
        if asyncio.iscoroutinefunction(result):
            return function(result, self.__loop)
        else:
            return result
